package com.uj.speedcalculator;

import java.util.Locale;

import android.os.Bundle;
import android.util.SparseArray;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;

public class MainActivity extends MyActivity {
	static int currentMode = Calculations.metersMode,
			currentView = R.layout.activity_goal;
	Button currentModeButton;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		try{
			String lng = Locale.getDefault().getLanguage();
			if(lng.equalsIgnoreCase("en"))
			{
				currentMode=Calculations.milesMode;
			}
		}catch(Exception e){}
		
		setContentView(currentView);
		setCurrentDistanceMode();
		appendListeners();
	}

	public void switchView(View view) {
		SparseArray<Double> values = getValues();
		switch (view.getId()) {
		case R.id.btn_speed:
			currentView = R.layout.activity_speed;
			break;
		case R.id.btn_goal:
		default:
			currentView = R.layout.activity_goal;
		}
		setContentView(currentView);
		setCurrentDistanceMode();
		setValues(values);
		appendListeners();
	}

	private void appendListeners() {
		switch (currentView) {
		case R.layout.activity_speed:
			((EditText) findViewById(R.id.inpt_first))
					.addTextChangedListener(new MyTextWatcher() {
						@Override
						protected void localTextChangeHandler(double v) {
							setText(R.id.inpt_second,
									Calculations.getNikeStyleSpeed(v));
							setText(R.id.inpt_third, Calculations
									.getOppositeSpeed(v, currentMode));
							updateSpdGlTimeBaseOnDistacte();
						}
					});

			((EditText) findViewById(R.id.inpt_second))
					.addTextChangedListener(new MyTextWatcher() {
						@Override
						protected void localTextChangeHandler(double v) {
							v = Calculations.getNikeStyleSpeed(v);
							setText(R.id.inpt_first, v);
							setText(R.id.inpt_third, Calculations
									.getOppositeSpeed(v, currentMode));
							updateSpdGlTimeBaseOnDistacte();
						}
					});
			((EditText) findViewById(R.id.inpt_third))
					.addTextChangedListener(new MyTextWatcher() {
						@Override
						protected void localTextChangeHandler(double v) {
							v = Calculations.getOppositeSpeed(v, currentMode);
							setText(R.id.inpt_first, v);
							setText(R.id.inpt_second,
									Calculations.getNikeStyleSpeed(v));
							updateSpdGlTimeBaseOnDistacte();
						}
					});
			((EditText) findViewById(R.id.inpt_distance))
					.addTextChangedListener(new MyTextWatcher() {
						@Override
						protected void localTextChangeHandler(double v) {
							updateSpdGlTimeBaseOnDistacte();
						}
					});
			((EditText) findViewById(R.id.inpt_time))
					.addTextChangedListener(new MyTextWatcher() {
						@Override
						protected void localTextChangeHandler(double v) {
							updateSpdGlDistanceOnTime();
						}
					});

			((Spinner) findViewById(R.id.distanceList))
					.setOnItemSelectedListener(new MySpeedDistanceListener());
			((Spinner) findViewById(R.id.timeList))
					.setOnItemSelectedListener(new MySpeedDistanceListener());

			break;
		case R.layout.activity_goal:
			((EditText) findViewById(R.id.inpt_distance))
					.addTextChangedListener(new MyGoalSectionListener());
			((EditText) findViewById(R.id.inpt_time))
					.addTextChangedListener(new MyGoalSectionListener());

			((Spinner) findViewById(R.id.distanceList))
					.setOnItemSelectedListener(new MyGoalSectionListener());
			((Spinner) findViewById(R.id.timeList))
					.setOnItemSelectedListener(new MyGoalSectionListener());
			break;
		}
	}

	private void setCurrentDistanceMode() {
		switch (currentMode) {
		case Calculations.milesMode:
			currentModeButton = (Button) findViewById(R.id.btn_miles);
			setNewTxtForTxtVw(R.id.first, R.string.lbl_f_miles);
			setNewTxtForTxtVw(R.id.second, R.string.lbl_s_miles);
			setNewTxtForTxtVw(R.id.third, R.string.lbl_t_miles);
			setNewList(R.id.distanceList, R.array.list_miles);
			break;
		case Calculations.metersMode:
		default:
			currentModeButton = (Button) findViewById(R.id.btn_meters);
			setNewTxtForTxtVw(R.id.first, R.string.lbl_f_meters);
			setNewTxtForTxtVw(R.id.second, R.string.lbl_s_meters);
			setNewTxtForTxtVw(R.id.third, R.string.lbl_t_meters);
			setNewList(R.id.distanceList, R.array.list_meters);
		}
		currentModeButton.setEnabled(false);
	}

	public void setMMs(View v) {
		Button btn = (Button) v;
		currentModeButton.setEnabled(true);
		currentModeButton = btn;
		currentModeButton.setEnabled(false);
		switch (v.getId()) {
		case R.id.btn_meters:
			currentMode = Calculations.metersMode;
			break;
		case R.id.btn_miles:
			currentMode = Calculations.milesMode;
			break;
		}
		setCurrentDistanceMode();
	}

	private void calculateGoal() {
		double goalDistance = getGoalDistance();
		double goalTime = getGoalTime();
		double speed = goalDistance / goalTime;
		setText(R.id.inpt_first, speed);
		setText(R.id.inpt_second, Calculations.getNikeStyleSpeed(speed));
		setText(R.id.inpt_third,
				Calculations.getOppositeSpeed(speed, currentMode));
	}

	protected void updateSpdGlTimeBaseOnDistacte() {
		double speed = getEditTextDouble(R.id.inpt_first);
		double distance = getGoalDistance();
		if (distance == 0 || Double.isNaN(distance)
				|| Double.isInfinite(distance)) {
			EditText inp = (EditText) findViewById(R.id.inpt_distance);
			if (!inp.hasFocus())
				setText(R.id.inpt_distance, 10);
		} else {
			Spinner spn = (Spinner) findViewById(R.id.timeList);
			int timeLevel = spn.getSelectedItemPosition();
			double result = Calculations.getTimeForDistance(speed, distance,
					timeLevel);
			setText(R.id.inpt_time, result);
		}
	}

	protected void updateSpdGlDistanceOnTime() {
		double speed = getEditTextDouble(R.id.inpt_first);
		double time = getGoalTime();
		if (time == 0 || Double.isNaN(time) || Double.isInfinite(time)) {
			EditText inp = (EditText) findViewById(R.id.inpt_time);
			if (!inp.hasFocus())
				setText(R.id.inpt_distance, 1);
		} else {
			Spinner spn = (Spinner) findViewById(R.id.distanceList);
			int distanceLevel = spn.getSelectedItemPosition();
			double result = Calculations.getDistanceForTime(speed, time,
					distanceLevel, currentMode);
			setText(R.id.inpt_distance, result);
		}
	}

	private double getGoalDistance() {
		double goalDistance = getEditTextDouble(R.id.inpt_distance);
		Spinner spn = (Spinner) findViewById(R.id.distanceList);
		int pos = spn.getSelectedItemPosition();
		return Calculations.getDistance(goalDistance, pos, currentMode);
	}

	private double getGoalTime() {
		double goalTime = getEditTextDouble(R.id.inpt_time);
		Spinner spn = (Spinner) findViewById(R.id.timeList);
		int pos = spn.getSelectedItemPosition();
		return Calculations.getTimeInHrs(goalTime, pos);
	}

	/**
	 * Gets current values before switching layout
	 * 
	 * @return
	 */
	private SparseArray<Double> getValues() {
		SparseArray<Double> values = new SparseArray<Double>();
		values.append(R.id.inpt_first, getEditTextDouble(R.id.inpt_first));
		values.append(R.id.inpt_second, getEditTextDouble(R.id.inpt_second));
		values.append(R.id.inpt_third, getEditTextDouble(R.id.inpt_third));
		values.append(R.id.inpt_time, getEditTextDouble(R.id.inpt_time));
		values.append(R.id.inpt_distance, getEditTextDouble(R.id.inpt_distance));
		values.append(R.id.timeList,
				(double) ((Spinner) findViewById(R.id.timeList))
						.getSelectedItemPosition());
		values.append(R.id.distanceList,
				(double) ((Spinner) findViewById(R.id.distanceList))
						.getSelectedItemPosition());
		return values;
	}

	/**
	 * Sets current values after switching layout
	 * 
	 * @return2
	 */
	@Override
	SparseArray<Double> localSetValues(SparseArray<Double> values) {
		int selection = (int) (double) values.get(R.id.timeList, 0.0);
		((Spinner) findViewById(R.id.timeList)).setSelection(selection);
		selection = (int) (double) values.get(R.id.distanceList, 0.0);
		((Spinner) findViewById(R.id.distanceList)).setSelection(selection);
		values.remove(R.id.timeList);
		values.remove(R.id.distanceList);
		return values;
	}

	class MyGoalSectionListener extends MyTextWatcher implements
			OnItemSelectedListener {
		@Override
		public void onTextChanged(CharSequence s, int start, int before,
				int count) {
			calculateGoal();
		}

		@Override
		public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2,
				long arg3) {
			calculateGoal();
		}

		@Override
		public void onNothingSelected(AdapterView<?> arg0) {
		}
	}

	class MySpeedDistanceListener implements
			OnItemSelectedListener {
		@Override
		public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2,
				long arg3) {
			MyTextWatcher.canUpdate = false;
			setText(R.id.inpt_third, Calculations.getOppositeSpeed(
					getEditTextDouble(R.id.inpt_first), currentMode));
			EditText inp = (EditText) findViewById(R.id.inpt_time);
			if (!inp.hasFocus()) {
				updateSpdGlTimeBaseOnDistacte();
			} else {
				updateSpdGlDistanceOnTime();
			}
			MyTextWatcher.canUpdate = true;
		}
		@Override
		public void onNothingSelected(AdapterView<?> arg0) {
		}
	}

}
